package java11;

import java.util.concurrent.locks.ReentrantLock;

public class FizzBuzz {
	private int num;
	private ReentrantLock lock=new ReentrantLock();
	private int startnum=1;
	
	 public FizzBuzz(int n){
		this.num=n; 
	 }             
	 public void fizz(Printer printFizz) throws InterruptedException{
		  while(true){
			  synchronized (lock) {
				  while(startnum<=num&&(startnum%3!=0||startnum%5==0)){
					  lock.wait();
				  }
				  if(startnum>num){
					  return;
				  }
				  printFizz.run();
				  startnum++;
				  lock.notifyAll();
			}
		  }
	 }          
	 public void buzz(Printer printBuzz) throws InterruptedException{
		 while(true){
			  synchronized (lock) {
				  while(startnum<=num&&(startnum%3==0||startnum%5!=0)){
					  lock.wait();
				  }
				  if(startnum>num){
					  return;
				  }
				  printBuzz.run();
				  startnum++;
				  lock.notifyAll();
			}
		  }
	 }          
	 public void fizzbuzz(Printer printFizzBuzz) throws InterruptedException{
		 while(true){
			  synchronized (lock) {
				  while(startnum<=num&&(startnum%3!=0||startnum%5!=0)){
					  lock.wait();
				  }
				  if(startnum>num){
					  return;
				  }
				  printFizzBuzz.run();
				  startnum++;
				  lock.notifyAll();
			}
		  }
	 }  
	 public void number() throws InterruptedException{
		 while(true){
			  synchronized (lock) {
				  while(startnum<=num&&(startnum%3==0||startnum%5==0)){
					  lock.wait();
				  }
				  if(startnum>num){
					  return;
				  }
				  Numprinter np=new Numprinter(startnum);
				  np.run();
				  startnum++;
				  lock.notifyAll();
			}
		  }
	 }
	public int getStartnum() {
		return startnum;
	}
	public void setStartnum(int startnum) {
		this.startnum = startnum;
	}      
}
